import os
import requests
import subprocess

def download_and_merge_m3u8(m3u8_url, output_dir='downloads', mp4_filename=None):
    os.makedirs(output_dir, exist_ok=True)
    resp = requests.get(m3u8_url)
    resp.raise_for_status()
    m3u8_content = resp.text
    ts_urls = []
    base_url = m3u8_url.rsplit('/', 1)[0]
    for line in m3u8_content.splitlines():
        if line and not line.startswith('#'):
            if line.startswith('http'):
                ts_urls.append(line)
            else:
                ts_urls.append(base_url + '/' + line)
    ts_files = []
    for idx, ts_url in enumerate(ts_urls):
        ts_name = f'{idx:05d}.ts'
        ts_path = os.path.join(output_dir, ts_name)
        ts_files.append(ts_path)
        if not os.path.exists(ts_path):
            r = requests.get(ts_url, stream=True)
            with open(ts_path, 'wb') as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
    list_path = os.path.join(output_dir, 'ts_list.txt')
    with open(list_path, 'w', encoding='utf-8') as f:
        for ts_file in ts_files:
            f.write(f"file '{os.path.abspath(ts_file)}'\n")
    # 生成 mp4 文件名
    if mp4_filename is None:
        mp4_filename = os.path.basename(output_dir) + '.mp4'
    mp4_path = os.path.join(output_dir, mp4_filename)
    ffmpeg_path = r'C:\ffmpeg-7.1.1-essentials_build\bin\ffmpeg.exe'
    cmd = [
        ffmpeg_path, '-f', 'concat', '-safe', '0', '-i', list_path,
        '-c:v', 'copy', '-c:a', 'aac', '-strict', '-2', mp4_path, '-y'
    ]
    result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False)
    # 判断 mp4 是否生成且大于1MB
    if os.path.exists(mp4_path) and os.path.getsize(mp4_path) > 1024 * 1024:
        # 合并成功后删除 ts 文件和 ts_list.txt
        for f in os.listdir(output_dir):
            if f.endswith('.ts') or f == 'ts_list.txt':
                try:
                    os.remove(os.path.join(output_dir, f))
                except Exception:
                    pass
        return mp4_path
    else:
        raise Exception(f"ffmpeg 合并失败: {result.stderr.decode('utf-8')}") 